/*
 * ifile_server_comms.cpp
 *
 *  Created on: 2 Apr 2011
 *      Author: cccp
 */

#include "headers/http_post_stream.hpp"

#include <QByteArray>
#include <QList>
#include <QMetaType>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QString>


//#include <QObject>

#ifndef IFILE_SERVER_COMMS_HPP
#define IFILE_SERVER_COMMS_HPP

class IfileServerComms : public QObject
{
    Q_OBJECT

public:
        IfileServerComms(QString _apiKey);
        ~IfileServerComms();

    struct FileStatusResponse
    {
        QString     status;
        uint        fileStatus;
        QString     fileStatusMsg;
        QString     fileKey;
        int         errorCode;
    };

    struct UploadFileResponse
    {
        QString     status;
        QString     url;
        QString     fileKey;
        qint64      fileSize;
        QString     fileMd5;
        QString     fileMime;
        QString     fileName;
        QString     hash;
        int         errorCode;
    };

    struct UploadServerResponse
    {
        QString     status;
        uint        serverId;
        int         errorCode;
    };

    struct FilePropertiesResponse
    {
        QString     status;
        QString     fileKey;
        QString     fileName;
        QString     fileMd5;
        qint64      fileSize;
        QString     fileMime;
        uint        serverId;
        qint64      fileTimeStampUpload;
        qint64      fileTimeStampChecked;
        qint64      fileTimeStampAccessed;
        uint        fileNumDownloaded;
        int         errorCode;
    };

    struct RenameFileResponse
    {
        QString     status;
        QString     fileKey;
        QString     fileName;
        int         errorCode;
    };

    struct RemoveFileResponse
    {
        QString     status;
        QString     fileKey;
        int         errorCode;
    };

    struct FileDescriptionResponse
    {
        QString     status;
        QString     fileKey;
        QString     fileDescription;
        int         errorCode;
    };

    struct FolderDetails
    {
        QString     status;
        qint64      numberOfFiles;
        QString     folderName;
        QString     folderKey;
        qint64      folderType;
        int         errorCode;

    };

    struct AccountStatsResponse
    {
        QString     status;
        qint64      storgaeUsed;
        qint64      bandwidthUsed;
        qint64      numberOfFiles;
        int         errorCode;
    };

    struct FileDetails
    {
        QString     status;
        qint64      fileSize;
        QString     fileName;
        QString     fileDescription;
        QString     fileKey;
        QString     hash;
        int         errorCode;
    };

    struct HttpError
    {
        QString     status;
        int         errorCode;
    };

    QString getApiKey();
    void    setFolderKey(QString folderKey);

    int    uploadFile(QString uploadFile, uint serverId);
    int    getUploadServerId();
    int    getFileStatus(QString fileKey);
    int    getFileProperties(QString fileKey);
    int    renameFile(QString fileKey, QString renameFileResponse);
    int    removeFile(QString fileKey);
    int    editFileDescription(QString fileKey, QString newFileDes);
    int    listFolders();
    int    getAccountStats();
    int    listFiles(uint numOfPages, QString oderFileBy, QString orderDirection);
    //int     downloadFile(QString downloadLocation, QString fileKey);

    int    getUploadProgress();
    //int    getDownloadProgress();


public slots:

    void    uploadReplyFinished(QNetworkReply *);
    void    serverIdReplyFinished(QNetworkReply *);
    void    setUploadProgress(qint64 bytesSent, qint64 bytesTotal);
    void    setDownloadProgress(qint64 bytesSent, qint64 bytesTotal);
    void    fileStatusReplyFinished(QNetworkReply *);
    void    filePropertiesReplyFinished(QNetworkReply *);
    void    renameFileReplyFinished(QNetworkReply *);
    void    removeFileReplyFinished(QNetworkReply *);
    void    editFileDesReplyFinished(QNetworkReply *);
    void    accountStatsReplyFinished(QNetworkReply *);
    void    listFoldersReplyFinished(QNetworkReply *);
    void    listFilesReplyFinished(QNetworkReply *);

    void    httpReplyError(QNetworkReply::NetworkError);


signals:

    void    uploadFinished(IfileServerComms::UploadFileResponse);
    void    serverIdFinished(IfileServerComms::UploadServerResponse);
    void    fileStatusFinished(IfileServerComms::FileStatusResponse);
    void    filePropertiesFinished(IfileServerComms::FilePropertiesResponse);
    void    renameFileFinished(IfileServerComms::RenameFileResponse);
    void    removeFileFinished(IfileServerComms::RemoveFileResponse);
    void    editFileDesFinished(IfileServerComms::FileDescriptionResponse);
    void    accountStatsFinished(IfileServerComms::AccountStatsResponse);
    void    listFoldersFinished(QList<IfileServerComms::FolderDetails>);
    void    listFilesFinished(QList<IfileServerComms::FileDetails>);
    void    uploadProgress(int);
    void    httpReplyError(IfileServerComms::HttpError);


private:

    QString         createMessageBoundary();
    QVariantMap     parseJson(QByteArray jsonReply);
    QVariantMap     parseJsonFolders(QByteArray jsonReply);
    QVariantMap     parseJsonFiles(QByteArray jsonReply);

    QNetworkAccessManager * uploadManager;
    QNetworkAccessManager * serverIdManager;
    QNetworkAccessManager * fileStatusManager;
    QNetworkAccessManager * fileProManager;
    QNetworkAccessManager * renameFileManager;
    QNetworkAccessManager * removeFileManager;
    QNetworkAccessManager * editFileDesManager;
    QNetworkAccessManager * acountStatsManager;
    QNetworkAccessManager * listFoldersManager;
    QNetworkAccessManager * listFilesManager;

    QString apiKey;
    QString folderKey;

    int uploadProgressLevel;
    int downloadProgressLevel;

    HttpPostStream * ioPostStream;
    QNetworkReply * reply;
};

Q_DECLARE_METATYPE(IfileServerComms::FileStatusResponse);
Q_DECLARE_METATYPE(IfileServerComms::UploadServerResponse);
Q_DECLARE_METATYPE(IfileServerComms::UploadFileResponse);

#endif /* IFILE_SERVER_COMMS_HPP*/
